﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;

namespace CSharpExperiments
{
	public sealed class Singletons : Singleton<Singletons>
	{
		private readonly ConcurrentDictionary<Type, Object> values = new ConcurrentDictionary<Type, Object>();

		public T Get<T>() where T : new()
		{
			return (T) values.GetOrAdd(typeof(T), type => new T());
		}

		public bool Remove<T>()
		{
			return Remove(typeof(T));
		}

		public bool Remove(Type type)
		{
			Object val;
			return values.TryRemove(type, out val);
		}

		public void Clear()
		{
			values.Clear();
		}
	}

	public abstract class Singleton<T> where T : Singleton<T>, new ()
	{
		private static readonly Lazy<Singletons> singletons = new Lazy<Singletons>();

		public static T Current
		{
			get
			{
				if (typeof(T) == typeof(Singletons))
					return (T) (Object) singletons.Value;

				return Singletons.Current.Get<T>();
			}
		}
	}
}
